/////////////////////////////////////////////////////////////////////////////
// Name:        variantref.h
// Purpose:     Base classes for reference-counted variant types
// Author:      Julian Smart
// Modified by:
// Created:     2006-05-11
// RCS-ID:      $$
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _WX_VARIANTREF_H_
#define _WX_VARIANTREF_H_

#include "wx/defs.h"
#include "wx/variant.h"

/*
 * wxVariantRefData is a wxVariantData object that is ref counted (holds and shares
 * the actual data). It doesn't get set directly into a wxVariant, but is stored
 * by a wxRefCountingVariantData object.
 *
 * We're not using the wxObject ref counting mechanism because we wish to
 * use RTTI in out referenced data, rather than deriving from wxObjectRefData.
 * Or could we derive from both? Possibly.

 */

class wxVariantRefData: public wxVariantData
{
DECLARE_CLASS(wxVariantRefData)
public:

// Construction & destruction

    wxVariantRefData():m_count(1) { }

    virtual void Copy(wxVariantData& data) = 0;

// NEW OPERATIONS

    int GetCount() const { return m_count; }
    void Inc() { m_count ++; }
    void Dec() { m_count --; }

private:

    int             m_count;
};

/*
 * wxRefCountingVariantData is a wxVariantData object that can do ref counting (points to a wxVariantRefData)
 */

class wxRefCountingVariantData: public wxVariantData
{
DECLARE_CLASS(wxRefCountingVariantData)
public:

// Construction & destruction

    wxRefCountingVariantData(wxVariantRefData* data) { m_variantRefData = data; }
    wxRefCountingVariantData() { m_variantRefData = NULL; }
    ~wxRefCountingVariantData() { Unref(); }

// OVERRIDEABLES

    /// Copy to data
    virtual void Copy(wxVariantData& data);
    virtual bool Eq(wxVariantData& data) const;
    virtual bool Write(wxString& str) const;
    virtual bool Read(wxString& str);

    // What type is it? Return a string name.
    virtual wxString GetType() const { return m_variantRefData ? m_variantRefData->GetType() : wxString(wxT("null")); }

// NEW OPERATIONS

    void Ref(const wxRefCountingVariantData& data);
    void Unref();
    virtual wxVariantRefData* CreateVariantRefData() = 0;
    wxVariantRefData* CloneVariantRefData(const wxVariantRefData* refData);

    /// Make sure we're the exclusive owner of the data
    void AllocExclusive();

    wxVariantRefData* GetVariantRefData() const { return m_variantRefData; }


private:

    wxVariantRefData*   m_variantRefData;
};

/*! wxVariant was stuffed up when made reference counting - there's no provision
 * for cloning data, and therefore no AllocExclusive. Aaaargh.
 * So we have to use this class to make at least our own variant data copyable.
 */

class wxClonableVariantData: public wxVariantData
{
DECLARE_CLASS(wxClonableVariantData)
public:

// Construction & destruction

    wxClonableVariantData() {}

    virtual wxVariantData* Clone() = 0;
};

// wxWidgets is missing AllocExclusive for wxVariant
void wxVariantAllocExclusive(wxVariant& variant);

#endif
    // _WX_VARIANTREF_H_
